package com.meilai.project.service.business.workbench.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.meilai.project.dto.business.workbench.FillReasonsForNotCooperatingDTO;
import com.meilai.project.entity.business.customer.CustomerInfo;
import com.meilai.project.entity.business.customer.CustomerVisitComments;
import com.meilai.project.entity.business.workbench.*;
import com.meilai.project.service.business.customer.CustomerInfoService;
import com.meilai.project.service.business.customer.CustomerVisitCommentsService;
import com.meilai.project.service.business.workbench.*;
import com.meilai.project.vo.business.workbench.*;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class CompanyMonthServiceImpl implements CompanyMonthService {

    @Autowired
    private YearWeekService yearWeekService;

    @Autowired
    private YearService yearService;

    @Autowired
    private SaleWeekTargetService saleWeekTargetService;

    @Autowired
    private CustomerInfoService customerInfoService;

    @Autowired
    private CustomerEstimateRecordService customerEstimateRecordService;

    @Autowired
    private SaleWeekCustomerTargetService saleWeekCustomerTargetService;

    @Autowired
    private CustomerVisitCommentsService customerVisitCommentsService;

    @Override
    public CompanyMonthTargetVO queryCompanyMonthByMonth(Integer year, Integer month) {
        BigDecimal hundred = new BigDecimal(100);
        CompanyMonthTargetVO vo = new CompanyMonthTargetVO();
        vo.setMonth(month);
        Year one = yearService.getOne(Wrappers.<Year>lambdaQuery().eq(Year::getYear, year).eq(Year::getType, month <= 6 ? 1 : 2));
        if (one == null) {
            one = new Year();
            one.setYear("-1");
            one.setType(-1);
        }
        List<YearWeek> list = yearWeekService.list(Wrappers.<YearWeek>lambdaQuery().eq(YearWeek::getYear_id, one.getId()).eq(YearWeek::getMonth, month));
        LocalDate month_begin = LocalDate.of(year, month, 1);
        LocalDate month_end = month_begin.with(TemporalAdjusters.lastDayOfMonth());
        List<CompanyMonthWeekTargetVO> companyThisMonthWeekTargetVOList = new ArrayList<>();
        BigDecimal zero = new BigDecimal(0).setScale(2, RoundingMode.HALF_UP);
        BigDecimal all_amount_count = new BigDecimal(0);
        BigDecimal all_target_count = new BigDecimal(0);
        if (CollectionUtils.isNotEmpty(list)) {
            List<Long> week_ids = list.stream().map(YearWeek::getId).collect(Collectors.toList());
            Map<Long, List<BaseSaleWeekTargetVO>> week_sale_map = saleWeekTargetService.querySaleWeekListByWeekIds(week_ids, month_begin, month_end).stream().collect(Collectors.groupingBy(BaseSaleWeekTargetVO::getWeek_id));
            for (YearWeek week : list) {
                CompanyMonthWeekTargetVO weekTargetVO = new CompanyMonthWeekTargetVO();
                weekTargetVO.setWeek_id(week.getId());
                weekTargetVO.setMonth(month);
                weekTargetVO.setBegin_date(week.getBegin_date());
                weekTargetVO.setEnd_date(week.getEnd_date());
                List<BaseSaleWeekTargetVO> baseSaleWeekTargetVOList = week_sale_map.getOrDefault(weekTargetVO.getWeek_id(), new ArrayList<>());
                BigDecimal amount_count = new BigDecimal(0);
                BigDecimal target_count = new BigDecimal(0);
                for (BaseSaleWeekTargetVO baseSaleWeekTargetVO : baseSaleWeekTargetVOList) {
                    amount_count = amount_count.add(Optional.ofNullable(baseSaleWeekTargetVO.getContract_amount()).orElse(BigDecimal.ZERO));
                    target_count = target_count.add(Optional.ofNullable(baseSaleWeekTargetVO.getTarget()).orElse(BigDecimal.ZERO));
                }
                all_target_count = all_target_count.add(target_count);
                all_amount_count = all_amount_count.add(amount_count);
                weekTargetVO.setTarget(target_count);
                weekTargetVO.setContract_amount(amount_count);
                if (target_count.compareTo(zero) > 0) {
                    weekTargetVO.setCompletion_rate(amount_count.divide(target_count, 2, RoundingMode.HALF_UP).multiply(hundred));
                } else {
                    weekTargetVO.setCompletion_rate(zero);
                }
                weekTargetVO.setSaleWeekTargetVOList(baseSaleWeekTargetVOList);
                companyThisMonthWeekTargetVOList.add(weekTargetVO);
            }
        }
        vo.setCompanyThisMonthWeekTargetVOList(companyThisMonthWeekTargetVOList);
        vo.setTarget(all_target_count);
        vo.setContract_amount(all_amount_count);
        vo.setCompletion_rate(all_target_count.compareTo(zero) > 0 ? all_amount_count.divide(all_target_count, 2, RoundingMode.HALF_UP).multiply(hundred) : zero);
        return vo;
    }

    @Override
    public CompanyMonthPlanTargetVO queryCompanyMonthPlanByMonth(Integer year, Integer month) {
        CompanyMonthPlanTargetVO vo = new CompanyMonthPlanTargetVO();
        LocalDate date = LocalDate.of(year, month, 1);
        // 加一个月
        if (date.getMonthValue() == 12) {
            date = LocalDate.of(date.getYear() + 1, 1, 1);
        } else {
            date = LocalDate.of(date.getYear(), date.getMonthValue() + 1, 1);
        }
        Year one = yearService.getOne(Wrappers.<Year>lambdaQuery().eq(Year::getYear, date.getYear()).eq(Year::getType, date.getMonthValue() <= 6 ? 1 : 2));
        if (one == null) {
            one = new Year();
            one.setYear("-1");
            one.setType(-1);
        }
        vo.setMonth(date.getMonthValue());
        List<YearWeek> list = yearWeekService.list(Wrappers.<YearWeek>lambdaQuery().eq(YearWeek::getYear_id, one.getId()).eq(YearWeek::getMonth, date.getMonthValue()));
        List<NextMonthWeekCustomerVO> weekCustomerVOList = new ArrayList<>();
        BigDecimal month_target = new BigDecimal(0);
        if (CollectionUtils.isNotEmpty(list)) {
            List<Long> week_ids = list.stream().map(YearWeek::getId).collect(Collectors.toList());
            // 查询客户根据ID进行分组
            Map<Long, List<CustomerInfo>> customer_map = customerInfoService.list(Wrappers.<CustomerInfo>lambdaQuery().isNull(CustomerInfo::getDeleted_at)).stream().collect(Collectors.groupingBy(CustomerInfo::getId));
            Map<Long, List<SaleWeekTarget>> sale_week_target_map = saleWeekTargetService.list(Wrappers.<SaleWeekTarget>lambdaQuery().in(SaleWeekTarget::getWeek_id, week_ids)).stream().collect(Collectors.groupingBy(SaleWeekTarget::getWeek_id));
            // 查询下个月的目标数据
            List<SaleWeekCustomerTarget> saleWeekCustomerTargetList = saleWeekCustomerTargetService.list(Wrappers.<SaleWeekCustomerTarget>lambdaQuery().in(SaleWeekCustomerTarget::getWeek_id, week_ids));
            for (YearWeek week : list) {
                BigDecimal target = new BigDecimal(0);
                NextMonthWeekCustomerVO nextMonthWeekCustomerVO = new NextMonthWeekCustomerVO();
                nextMonthWeekCustomerVO.setMonth(date.getMonthValue());
                nextMonthWeekCustomerVO.setWeek_id(week.getId());
                nextMonthWeekCustomerVO.setBegin_date(week.getBegin_date());
                nextMonthWeekCustomerVO.setEnd_date(week.getEnd_date());
                Map<Long, List<SaleWeekCustomerTarget>> collect = saleWeekCustomerTargetList.stream().filter(item -> item.getWeek_id().equals(week.getId())).collect(Collectors.groupingBy(SaleWeekCustomerTarget::getCustomer_id));
                if (sale_week_target_map.containsKey(week.getId())) {
                    List<SaleWeekTarget> saleWeekTargetList = sale_week_target_map.get(week.getId());
                    for (SaleWeekTarget saleWeekTarget : saleWeekTargetList) {
                        target = target.add(saleWeekTarget.getTarget_quota());
                    }
                }
                // 加入每周的客户信息
                List<SaleWeekCustomerTargetVO> customerTargetVOList = new ArrayList<>();
                collect.forEach((customer_id, value) -> {
                    if (customer_map.containsKey(customer_id)) {
                        CustomerInfo customerInfo = customer_map.get(customer_id).get(0);
                        SaleWeekCustomerTargetVO saleWeekCustomerTargetVO = new SaleWeekCustomerTargetVO();
                        if (CollectionUtils.isNotEmpty(value)) {
                            BeanUtils.copyProperties(value.get(0), saleWeekCustomerTargetVO);
                            saleWeekCustomerTargetVO.setName(customerInfo.getName());
                            customerTargetVOList.add(saleWeekCustomerTargetVO);
                        }
                    }
                });
                nextMonthWeekCustomerVO.setCustomerTargetVOList(customerTargetVOList);
                nextMonthWeekCustomerVO.setTarget(target);
                month_target = month_target.add(target);
                weekCustomerVOList.add(nextMonthWeekCustomerVO);
            }
        }
        vo.setWeekCustomerVOList(weekCustomerVOList);
        vo.setTarget(month_target);
        return vo;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean fillReasonsForNotCooperating(List<FillReasonsForNotCooperatingDTO> dtoList) {
        return customerEstimateRecordService.updateBatchById(dtoList.stream().map(item -> {
            CustomerEstimateRecord record = new CustomerEstimateRecord();
            record.setId(item.getCustomer_estimate_record_id());
            record.setReasons_for_not_cooperating(item.getReasons_for_not_cooperating());
            return record;
        }).collect(Collectors.toList()));
    }

    @Override
    public Boolean fillAnnotation(Long customer_id, String comments) {
        CustomerVisitComments customerVisitComments = new CustomerVisitComments();
        customerVisitComments.setComments(comments);
        customerVisitComments.setCustomer_id(customer_id);
        customerVisitComments.setReceived_or_not(false);
        customerVisitComments.setCreated_time(LocalDateTime.now());
        return customerVisitCommentsService.save(customerVisitComments);
    }
}
